# -*- coding: utf-8 -*-
"""
管理员管理模块 - 视图层实现

本文件实现了测试DEMO中管理员管理相关的所有API视图，包括：

1. AdminAuthViewSet - 管理员认证视图集
   - login: 管理员登录，支持双因素认证
   - refresh_token: 刷新访问令牌
   - enable_2fa: 启用双因素认证
   - confirm_2fa: 确认双因素认证设置
   - disable_2fa: 禁用双因素认证
   - logout: 管理员登出
   - profile: 获取管理员个人信息

2. AdminDashboardViewSet - 管理员仪表板视图集
   - stats: 获取系统统计数据
   - recent_activities: 获取最近活动记录

3. AdminUserViewSet - 管理员用户管理视图集
   - 标准CRUD操作：创建、读取、更新、删除管理员用户
   - 权限控制：基于RBAC权限系统

4. RoleViewSet - 角色管理视图集
   - 标准CRUD操作：管理系统角色
   - permissions: 获取角色权限列表
   - assign_permissions: 为角色分配权限

5. PermissionViewSet - 权限管理视图集
   - 标准CRUD操作：管理系统权限

6. UserRoleViewSet - 用户角色管理视图集
   - assign_role: 为用户分配角色
   - remove_role: 移除用户角色

7. AuditLogViewSet - 审计日志视图集
   - 只读操作：查看系统操作日志
   - 支持多种过滤条件

8. SystemConfigViewSet - 系统配置管理视图集
   - 标准CRUD操作：管理系统配置参数

9. UserManagementViewSet - 用户管理视图集
   - 管理普通用户账户
   - activate/deactivate: 激活/停用用户

所有视图都集成了完整的权限控制、操作日志记录和安全验证机制。

Author: zhaozeliang
Date: 2025-09-06
"""

from rest_framework import viewsets, status, permissions
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.authtoken.models import Token
from django.contrib.auth import login, logout
from django.db.models import Q, Count
from django.utils import timezone
from django.http import JsonResponse
from .models import AdminUser, Role, Permission, AuditLog, SystemConfig
from .serializers import (
    AdminUserSerializer, RoleSerializer, PermissionSerializer,
    AuditLogSerializer, SystemConfigSerializer, AdminLoginSerializer, 
    AdminDashboardStatsSerializer, UserManagementSerializer
)
from users.models import User
from portfolios.models import Portfolio
from products.models import Product
from .permissions import (
    IsAdminUser, HasPermission, PermissionRequiredMixin, 
    permission_required, PermissionChecker, Permissions
)
from .authentication import JWTTokenGenerator, TwoFactorAuth, SecurityLogger
from .utils import log_admin_action, get_client_ip


class AdminAuthViewSet(viewsets.ViewSet):
    """
    管理员认证视图集
    """
    permission_classes = [permissions.AllowAny]
    
    @action(detail=False, methods=['post'])
    def login(self, request):
        """
        管理员登录
        """
        serializer = AdminLoginSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.validated_data['user']
            admin_user = serializer.validated_data['admin_user']
            
            # 检查是否启用双因素认证
            if admin_user.two_factor_enabled:
                totp_token = request.data.get('totp_token')
                if not totp_token:
                    return Response({
                        'error': '需要双因素认证令牌',
                        'requires_2fa': True
                    }, status=status.HTTP_400_BAD_REQUEST)
                
                if not TwoFactorAuth.verify_totp(admin_user.two_factor_secret, totp_token):
                    SecurityLogger.log_login_attempt(
                        user, get_client_ip(request), False, '双因素认证失败'
                    )
                    return Response({
                        'error': '双因素认证令牌无效'
                    }, status=status.HTTP_400_BAD_REQUEST)
            
            # 生成JWT token
            access_token = JWTTokenGenerator.generate_token(user)
            refresh_token = JWTTokenGenerator.generate_refresh_token(user)
            
            # 更新最后登录信息
            admin_user.last_login_ip = get_client_ip(request)
            admin_user.last_login_time = timezone.now()
            admin_user.save()
            
            # 记录登录日志
            SecurityLogger.log_login_attempt(
                user, get_client_ip(request), True
            )
            log_admin_action(
                user=user,
                action='admin_login',
                resource='admin_auth',
                ip_address=get_client_ip(request),
                user_agent=request.META.get('HTTP_USER_AGENT', ''),
                status='success'
            )
            
            return Response({
                'access_token': access_token,
                'refresh_token': refresh_token,
                'user': AdminUserSerializer(admin_user).data,
                'message': '登录成功'
            })
        
        # 记录登录失败日志
        log_admin_action(
            user=None,
            action='admin_login_failed',
            resource='admin_auth',
            ip_address=get_client_ip(request),
            user_agent=request.META.get('HTTP_USER_AGENT', ''),
            request_data=request.data,
            status='failed',
            error_message=str(serializer.errors)
        )
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    @action(detail=False, methods=['post'])
    def refresh_token(self, request):
        """
        刷新JWT令牌
        """
        refresh_token = request.data.get('refresh_token')
        if not refresh_token:
            return Response({
                'error': '缺少刷新令牌'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        try:
            user = JWTTokenGenerator.verify_refresh_token(refresh_token)
            access_token = JWTTokenGenerator.generate_token(user)
            new_refresh_token = JWTTokenGenerator.generate_refresh_token(user)
            
            return Response({
                'access_token': access_token,
                'refresh_token': new_refresh_token
            })
        except Exception as e:
            return Response({
                'error': '无效的刷新令牌'
            }, status=status.HTTP_401_UNAUTHORIZED)
    
    @action(detail=False, methods=['post'])
    def enable_2fa(self, request):
        """
        启用双因素认证
        """
        user = request.user
        admin_user = user.adminuser
        
        if admin_user.two_factor_enabled:
            return Response({
                'error': '双因素认证已启用'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        # 生成密钥和二维码
        secret = TwoFactorAuth.generate_secret()
        qr_code = TwoFactorAuth.generate_qr_code(user.username, secret)
        backup_codes = TwoFactorAuth.generate_backup_codes()
        
        # 临时保存密钥（用户确认后才正式启用）
        request.session['temp_2fa_secret'] = secret
        request.session['temp_backup_codes'] = backup_codes
        
        return Response({
            'secret': secret,
            'qr_code': qr_code,
            'backup_codes': backup_codes,
            'message': '请使用认证应用扫描二维码，然后输入验证码确认启用'
        })
    
    @action(detail=False, methods=['post'])
    def confirm_2fa(self, request):
        """
        确认启用双因素认证
        """
        user = request.user
        admin_user = user.adminuser
        totp_token = request.data.get('totp_token')
        
        if not totp_token:
            return Response({
                'error': '请输入验证码'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        secret = request.session.get('temp_2fa_secret')
        backup_codes = request.session.get('temp_backup_codes')
        
        if not secret:
            return Response({
                'error': '请先生成双因素认证密钥'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        if TwoFactorAuth.verify_totp(secret, totp_token):
            admin_user.two_factor_enabled = True
            admin_user.two_factor_secret = secret
            admin_user.backup_codes = backup_codes
            admin_user.save()
            
            # 清除临时数据
            del request.session['temp_2fa_secret']
            del request.session['temp_backup_codes']
            
            SecurityLogger.log_security_event(
                user, '启用双因素认证', get_client_ip(request)
            )
            
            return Response({
                'message': '双因素认证已成功启用'
            })
        else:
            return Response({
                'error': '验证码无效'
            }, status=status.HTTP_400_BAD_REQUEST)
    
    @action(detail=False, methods=['post'])
    def disable_2fa(self, request):
        """
        禁用双因素认证
        """
        user = request.user
        admin_user = user.adminuser
        password = request.data.get('password')
        
        if not password:
            return Response({
                'error': '请输入密码确认'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        if not user.check_password(password):
            return Response({
                'error': '密码错误'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        admin_user.two_factor_enabled = False
        admin_user.two_factor_secret = ''
        admin_user.backup_codes = []
        admin_user.save()
        
        SecurityLogger.log_security_event(
            user, '禁用双因素认证', get_client_ip(request)
        )
        
        return Response({
            'message': '双因素认证已禁用'
        })
    
    @action(detail=False, methods=['post'])
    def logout(self, request):
        """
        管理员登出
        """
        if request.user.is_authenticated:
            # 删除token
            try:
                token = Token.objects.get(user=request.user)
                token.delete()
            except Token.DoesNotExist:
                pass
            
            # 记录登出日志
            log_admin_action(
                user=request.user,
                action='admin_logout',
                resource='admin_auth',
                ip_address=get_client_ip(request),
                user_agent=request.META.get('HTTP_USER_AGENT', ''),
                status='success'
            )
            
            logout(request)
            return Response({'message': '登出成功'})
        
        return Response({'error': '用户未登录'}, status=status.HTTP_400_BAD_REQUEST)
    
    @action(detail=False, methods=['get'])
    def profile(self, request):
        """
        获取当前管理员信息
        """
        if request.user.is_authenticated:
            try:
                admin_user = AdminUser.objects.get(user=request.user)
                return Response(AdminUserSerializer(admin_user).data)
            except AdminUser.DoesNotExist:
                return Response({'error': '管理员信息不存在'}, status=status.HTTP_404_NOT_FOUND)
        
        return Response({'error': '用户未登录'}, status=status.HTTP_401_UNAUTHORIZED)


class AdminDashboardViewSet(viewsets.ViewSet):
    """
    管理后台仪表板视图集
    """
    permission_classes = [IsAdminUser]
    
    @action(detail=False, methods=['get'])
    def stats(self, request):
        """
        获取仪表板统计数据
        """
        # 统计用户数据
        total_users = User.objects.count()
        active_users = User.objects.filter(is_active=True).count()
        
        # 统计投资组合数据
        total_portfolios = Portfolio.objects.count()
        
        # 统计产品数据
        total_products = Product.objects.count()
        
        # 统计交易数据（假设有交易模型）
        total_transactions = 0  # 需要根据实际交易模型统计
        
        # 系统健康状态（简化版）
        system_health = 'healthy'
        
        stats_data = {
            'total_users': total_users,
            'active_users': active_users,
            'total_portfolios': total_portfolios,
            'total_products': total_products,
            'total_transactions': total_transactions,
            'system_health': system_health
        }
        
        serializer = AdminDashboardStatsSerializer(stats_data)
        return Response(serializer.data)
    
    @action(detail=False, methods=['get'])
    def recent_activities(self, request):
        """
        获取最近活动日志
        """
        recent_logs = AuditLog.objects.order_by('-created_at')[:20]
        serializer = AuditLogSerializer(recent_logs, many=True)
        return Response(serializer.data)


class AdminUserViewSet(viewsets.ModelViewSet):
    """
    管理员用户管理视图集
    """
    queryset = AdminUser.objects.all()
    serializer_class = AdminUserSerializer
    permission_classes = [IsAdminUser, HasPermission]
    required_permissions = {
        'list': 'admin_user:read',
        'retrieve': 'admin_user:read',
        'create': 'admin_user:create',
        'update': 'admin_user:update',
        'partial_update': 'admin_user:update',
        'destroy': 'admin_user:delete'
    }
    
    def perform_create(self, serializer):
        admin_user = serializer.save()
        log_admin_action(
            user=self.request.user,
            action='create_admin_user',
            resource='admin_user',
            resource_id=str(admin_user.id),
            ip_address=get_client_ip(self.request),
            user_agent=self.request.META.get('HTTP_USER_AGENT', ''),
            request_data=self.request.data,
            status='success'
        )
    
    def perform_update(self, serializer):
        admin_user = serializer.save()
        log_admin_action(
            user=self.request.user,
            action='update_admin_user',
            resource='admin_user',
            resource_id=str(admin_user.id),
            ip_address=get_client_ip(self.request),
            user_agent=self.request.META.get('HTTP_USER_AGENT', ''),
            request_data=self.request.data,
            status='success'
        )
    
    def perform_destroy(self, instance):
        log_admin_action(
            user=self.request.user,
            action='delete_admin_user',
            resource='admin_user',
            resource_id=str(instance.id),
            ip_address=get_client_ip(self.request),
            user_agent=self.request.META.get('HTTP_USER_AGENT', ''),
            status='success'
        )
        instance.delete()


class RoleViewSet(viewsets.ModelViewSet):
    """
    角色管理视图集
    """
    queryset = Role.objects.all()
    serializer_class = RoleSerializer
    permission_classes = [IsAdminUser, HasPermission]
    required_permissions = {
        'list': 'role:read',
        'retrieve': 'role:read',
        'create': 'role:create',
        'update': 'role:update',
        'partial_update': 'role:update',
        'destroy': 'role:delete'
    }
    
    @action(detail=True, methods=['get'])
    def permissions(self, request, pk=None):
        """
        获取角色的权限列表
        """
        role = self.get_object()
        permissions = role.permissions.all()
        serializer = PermissionSerializer(permissions, many=True)
        return Response(serializer.data)
    
    @action(detail=True, methods=['post'])
    def assign_permissions(self, request, pk=None):
        """
        为角色分配权限
        """
        role = self.get_object()
        permission_ids = request.data.get('permission_ids', [])
        
        # 清除现有权限
        role.permissions.clear()
        
        # 分配新权限
        for permission_id in permission_ids:
            try:
                permission = Permission.objects.get(id=permission_id)
                role.permissions.add(permission)
            except Permission.DoesNotExist:
                continue
        
        log_admin_action(
            user=request.user,
            action='assign_role_permissions',
            resource='role',
            resource_id=str(role.id),
            ip_address=get_client_ip(request),
            user_agent=request.META.get('HTTP_USER_AGENT', ''),
            request_data=request.data,
            status='success'
        )
        
        return Response({'message': '权限分配成功'})


class PermissionViewSet(viewsets.ModelViewSet):
    """
    权限管理视图集
    """
    queryset = Permission.objects.all()
    serializer_class = PermissionSerializer
    permission_classes = [IsAdminUser, HasPermission]
    required_permissions = {
        'list': 'permission:read',
        'retrieve': 'permission:read',
        'create': 'permission:create',
        'update': 'permission:update',
        'partial_update': 'permission:update',
        'destroy': 'permission:delete'
    }


class UserRoleViewSet(viewsets.ViewSet):
    """
    用户角色管理视图集
    """
    permission_classes = [IsAdminUser, HasPermission]
    
    @action(detail=False, methods=['post'])
    def assign_role(self, request):
        """
        为用户分配角色
        """
        user_id = request.data.get('user_id')
        role_id = request.data.get('role_id')
        
        try:
            admin_user = AdminUser.objects.get(user_id=user_id)
            role = Role.objects.get(id=role_id)
            admin_user.roles.add(role)
            
            log_admin_action(
                user=request.user,
                action='assign_user_role',
                resource='admin_user',
                resource_id=str(admin_user.id),
                ip_address=get_client_ip(request),
                user_agent=request.META.get('HTTP_USER_AGENT', ''),
                request_data=request.data,
                status='success'
            )
            
            return Response({'message': '角色分配成功'})
        except (AdminUser.DoesNotExist, Role.DoesNotExist) as e:
            return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)
    
    @action(detail=False, methods=['post'])
    def remove_role(self, request):
        """
        移除用户角色
        """
        user_id = request.data.get('user_id')
        role_id = request.data.get('role_id')
        
        try:
            admin_user = AdminUser.objects.get(user_id=user_id)
            role = Role.objects.get(id=role_id)
            admin_user.roles.remove(role)
            
            log_admin_action(
                user=request.user,
                action='remove_user_role',
                resource='admin_user',
                resource_id=str(admin_user.id),
                ip_address=get_client_ip(request),
                user_agent=request.META.get('HTTP_USER_AGENT', ''),
                request_data=request.data,
                status='success'
            )
            
            return Response({'message': '角色移除成功'})
        except (AdminUser.DoesNotExist, Role.DoesNotExist) as e:
            return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)


class AuditLogViewSet(viewsets.ReadOnlyModelViewSet):
    """
    审计日志视图集（只读）
    """
    queryset = AuditLog.objects.all()
    serializer_class = AuditLogSerializer
    permission_classes = [IsAdminUser, HasPermission]
    required_permissions = {
        'list': 'audit_log:read',
        'retrieve': 'audit_log:read'
    }
    
    def get_queryset(self):
        queryset = super().get_queryset()
        
        # 支持按用户筛选
        user_id = self.request.query_params.get('user_id')
        if user_id:
            queryset = queryset.filter(user_id=user_id)
        
        # 支持按操作筛选
        action = self.request.query_params.get('action')
        if action:
            queryset = queryset.filter(action__icontains=action)
        
        # 支持按资源筛选
        resource = self.request.query_params.get('resource')
        if resource:
            queryset = queryset.filter(resource=resource)
        
        # 支持按状态筛选
        status_filter = self.request.query_params.get('status')
        if status_filter:
            queryset = queryset.filter(status=status_filter)
        
        # 支持按时间范围筛选
        start_date = self.request.query_params.get('start_date')
        end_date = self.request.query_params.get('end_date')
        if start_date:
            queryset = queryset.filter(created_at__gte=start_date)
        if end_date:
            queryset = queryset.filter(created_at__lte=end_date)
        
        return queryset.order_by('-created_at')


class SystemConfigViewSet(viewsets.ModelViewSet):
    """
    系统配置管理视图集
    """
    queryset = SystemConfig.objects.all()
    serializer_class = SystemConfigSerializer
    permission_classes = [IsAdminUser, HasPermission]
    required_permissions = {
        'list': 'system_config:read',
        'retrieve': 'system_config:read',
        'create': 'system_config:create',
        'update': 'system_config:update',
        'partial_update': 'system_config:update',
        'destroy': 'system_config:delete'
    }
    
    def perform_create(self, serializer):
        config = serializer.save(updated_by=self.request.user)
        log_admin_action(
            user=self.request.user,
            action='create_system_config',
            resource='system_config',
            resource_id=str(config.id),
            ip_address=get_client_ip(self.request),
            user_agent=self.request.META.get('HTTP_USER_AGENT', ''),
            request_data=self.request.data,
            status='success'
        )
    
    def perform_update(self, serializer):
        config = serializer.save(updated_by=self.request.user)
        log_admin_action(
            user=self.request.user,
            action='update_system_config',
            resource='system_config',
            resource_id=str(config.id),
            ip_address=get_client_ip(self.request),
            user_agent=self.request.META.get('HTTP_USER_AGENT', ''),
            request_data=self.request.data,
            status='success'
        )


class UserManagementViewSet(viewsets.ModelViewSet):
    """
    用户管理视图集（管理员视角）
    """
    queryset = User.objects.all()
    serializer_class = UserManagementSerializer
    permission_classes = [IsAdminUser, HasPermission]
    required_permissions = {
        'list': 'user_management:read',
        'retrieve': 'user_management:read',
        'update': 'user_management:update',
        'partial_update': 'user_management:update',
        'destroy': 'user_management:delete'
    }
    
    def get_queryset(self):
        queryset = super().get_queryset()
        
        # 支持搜索
        search = self.request.query_params.get('search')
        if search:
            queryset = queryset.filter(
                Q(username__icontains=search) |
                Q(email__icontains=search) |
                Q(first_name__icontains=search) |
                Q(last_name__icontains=search)
            )
        
        # 支持按状态筛选
        is_active = self.request.query_params.get('is_active')
        if is_active is not None:
            queryset = queryset.filter(is_active=is_active.lower() == 'true')
        
        return queryset.order_by('-date_joined')
    
    @action(detail=True, methods=['post'])
    def activate(self, request, pk=None):
        """
        激活用户
        """
        user = self.get_object()
        user.is_active = True
        user.save()
        
        log_admin_action(
            user=request.user,
            action='activate_user',
            resource='user',
            resource_id=str(user.id),
            ip_address=get_client_ip(request),
            user_agent=request.META.get('HTTP_USER_AGENT', ''),
            status='success'
        )
        
        return Response({'message': '用户已激活'})
    
    @action(detail=True, methods=['post'])
    def deactivate(self, request, pk=None):
        """
        停用用户
        """
        user = self.get_object()
        user.is_active = False
        user.save()
        
        log_admin_action(
            user=request.user,
            action='deactivate_user',
            resource='user',
            resource_id=str(user.id),
            ip_address=get_client_ip(request),
            user_agent=request.META.get('HTTP_USER_AGENT', ''),
            status='success'
        )
        
        return Response({'message': '用户已停用'})
